#ifndef	_THREADS_POOL_H_
#define	_THREADS_POOL_H_

#include <pthread.h>
#include <vector>
#include "Parser.h"
#include "Globals.h"

using namespace std;

/*
 * Manages all the working threads in the system.
 */
class ThreadsPool
{
  public:
	/* Holds the data that each thread needs (such as it's ID, and results) */
	struct ThreadData
	{
		size_t id;
		ThreadData **allThreadsData;
		Parser **parsedChunks;

		/* The results, names and beginStrs that were gatherd during the chunks processing */
		///vector<Match*> *results;
		vector<Name *> *names;
		char* *beginStrs;
		size_t *badCharsSLN;
		size_t *badMM;

		off_t *chunkLengths;

		
		ThreadData(size_t id_) : 
			id(id_) ,
			parsedChunks(new Parser*[numOfFiles]),
			///results(new vector<Match*>[numOfFiles]),
			names(new vector<Name*>[numOfFiles]),
			beginStrs(new char*[numOfFiles]),
			badCharsSLN(new size_t[numOfFiles]),
			badMM(new size_t[numOfFiles]),
			chunkLengths(new off_t[numOfFiles])
		{}

		~ThreadData()
		{
			for (int i = 0; i < numOfFiles; i++)
			{
///				for (vector<Match*>::iterator it = results[i].begin(); it != results[i].end(); it++)
///					delete *it;
				for (vector<Name*>::iterator it = names[i].begin(); it != names[i].end(); it++)
					delete *it;
			}
			delete[] parsedChunks;
///			delete[] results;
			delete[] names;
			delete[] beginStrs;
			delete[] badCharsSLN;
			delete[] badMM;
			delete[] chunkLengths;
		}
	};

  private:
	pthread_t *threads;
	ThreadData **threadsData;

	/* Initializes the worker threads */
	void initializeThreads();

  public:
	/* C'tor - receives the number of worker threads to initialize (not including the one needed for the main thread) */
	ThreadsPool();

	~ThreadsPool();

	void runMainThread();

	/* Waits for all threads to stop execution. */
	void waitThreads();

};

extern ThreadsPool *pool;

#endif	/* _THREADS_POOL_H_ */
